/**
 * Create in 2012-4-17.
 */
package kit4j.common.task;

import kit4j.common.task.event.ConcurrentTaskStateChangeEventFirer;
import kit4j.common.task.event.TaskStateChangeEvent;
import kit4j.common.task.event.TaskStateChangeEventFirer;
import kit4j.common.task.event.TaskStateChangeListener;

/**
 * 抽象任务类型。该类型实现了默认的任务状态变更与事件监听机制，方便于创建用户自定义的任务类型。
 * 
 * @author MiniKnife
 * 
 */
public abstract class AbstractTask implements Task {

	/**
	 * 任务状态。
	 */
	private TaskState taskState;

	/**
	 * 任务状态变更事件发送器。
	 */
	private TaskStateChangeEventFirer taskStateChangeEventFirer;

	/**
	 * 创建一个抽象任务对象。
	 */
	public AbstractTask() {
		taskStateChangeEventFirer = new ConcurrentTaskStateChangeEventFirer();
		taskState = TaskState.READY;
	}

	/**
	 * @see kit4j.common.task.Task#addTaskStateChangeListener(kit4j.common.task.event.TaskStateChangeListener)
	 */
	@Override
	public void addTaskStateChangeListener(TaskStateChangeListener listener) {
		taskStateChangeEventFirer.addListener(listener);
	}

	/**
	 * @see kit4j.common.task.Task#removeTaskStateChangeListener(kit4j.common.task.event.TaskStateChangeListener)
	 */
	@Override
	public void removeTaskStateChangeListener(TaskStateChangeListener listener) {
		taskStateChangeEventFirer.removeListener(listener);
	}

	/**
	 * @see kit4j.common.task.Task#getTaskStateChangeListeners()
	 */
	@Override
	public TaskStateChangeListener[] getTaskStateChangeListeners() {
		return taskStateChangeEventFirer.getListeners();
	}

	/**
	 * 设置任务当前状态。
	 * @param taskState 要设置的任务状态
	 */
	protected void setTaskState(TaskState taskState) {
		if (!this.taskState.equals(taskState)) {
			fireTaskStateChangeEvent(this.taskState, taskState);
			this.taskState = taskState;
		}
	}

	/**
	 * 报告任务状态的改变。
	 * @param oldState 任务之前的状态
	 * @param currentState 任务当前的状态
	 */
	protected void fireTaskStateChangeEvent(TaskState oldState, TaskState currentState) {
		taskStateChangeEventFirer.fireEvent(new TaskStateChangeEvent(this, oldState, currentState));
	}

	/**
	 * @see kit4j.common.task.Task#start()
	 */
	@Override
	public void start() {
		setTaskState(TaskState.RUNNING);
		doStart();
		setTaskState(TaskState.COMPLETE);
	}

	abstract protected void doStart();

	/**
	 * @see kit4j.common.task.Task#pause()
	 */
	@Override
	public void pause() {
		setTaskState(TaskState.PAUSE);
		doPause();
	}

	abstract protected void doPause();

	/**
	 * @see kit4j.common.task.Task#resume()
	 */
	@Override
	public void resume() {
		setTaskState(TaskState.RUNNING);
		doResume();
	}

	/**
	 * 
	 */
	abstract protected void doResume();

	/**
	 * @see kit4j.common.task.Task#stop()
	 */
	@Override
	public void stop() {
		setTaskState(TaskState.STOP);
		doStop();
	}

	abstract protected void doStop();

	/**
	 * @see kit4j.common.task.Task#restart()
	 */
	@Override
	public void restart() {
		stop();
		start();
	}

	/**
	 * @see kit4j.common.task.Task#getTaskState()
	 */
	@Override
	public TaskState getTaskState() {
		return taskState;
	}

}
